package com.ideal.hadoopadmin.service.cluster.user;

import com.ideal.hadoopadmin.api.better.hdfs.HadoopHDFSAPI;
import com.ideal.hadoopadmin.api.better.kerberos.KerberosAPI;
import com.ideal.hadoopadmin.api.hdfs.HDFSAPI;
import com.ideal.hadoopadmin.api.kerberos.KDCAPI;
import com.ideal.hadoopadmin.api.linux.UserAPI;
import com.ideal.hadoopadmin.common.entity.Result;
import com.ideal.hadoopadmin.common.entity.ResultAPI;
import com.ideal.hadoopadmin.entity.cluster.ClusterUser;
import com.ideal.hadoopadmin.entity.cluster.user.Clientquota;
import com.ideal.hadoopadmin.entity.cluster.user.Hdfsquota;
import com.ideal.hadoopadmin.entity.cluster.user.Kbrconfig;
import com.ideal.hadoopadmin.mapper.webdb.cluster.ClusterUserMapper;
import com.ideal.hadoopadmin.mapper.webdb.cluster.user.KbrconfigMapper;
import com.ideal.hadoopadmin.service.cluster.ClusterMachineService;
import com.ideal.hadoopadmin.service.cluster.ParameterService;
import com.ideal.tools.ssh.common.CommonProperties;
import com.ideal.tools.ssh.context.ClusterContext;
import com.ideal.tools.ssh.entity.ContextResult;
import com.ideal.tools.ssh.entity.LinuxMachine;
import com.ideal.tools.ssh.result.LinuxResult;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by 袁颖 on 2016/2/26.
 */
@Service
public class KbrconfigService {
    @Resource
    private KbrconfigMapper kbrconfigMapper;
    @Resource
    private ParameterService parameterService;
    @Resource
    private ClusterUserMapper clusterUserMapper;
    @Resource
    private ClusterMachineService clusterMachineService;
    @Resource
    private ClientquotaService clientquotaService;
    @Resource
    private HdfsquotaService hdfsquotaService;
    //根据id查找kbr
    public Kbrconfig findByUserId(Long userId) {
        return kbrconfigMapper.findByUserId(userId);
    }

    //入库
    public void saveKbrDB(Kbrconfig kbrconfig, Long userId) {
        kbrconfig.setUserId(userId);
        kbrconfigMapper.save(kbrconfig);
    }

    //更新
    public void updateByUserId(Kbrconfig kbrconfig) {
        kbrconfig.setChangeTime(System.currentTimeMillis());
        kbrconfigMapper.updateByUserId(kbrconfig);
    }

    public List<String> updateKbrconfig(List<Long> userIds, Kbrconfig kbrconfig,List<Clientquota> clientquotaList) {
        List<String> messageList = new ArrayList<String>();
        for (Long userId : userIds) {
            //注释掉旧方法，调用新方法update20160802qinfengxia
            //List<LinuxResult> linuxResults = callKDCAPI(kbrconfig);
            //数据库里的machineIds
            Kbrconfig dbKbr = kbrconfigMapper.findById(kbrconfig.getId());
            String[]  dbMachineIdsArray = dbKbr.getMachineIds().split(",");
            //页面的machineIds
            String curMachineIds = kbrconfig.getMachineIds();
            //需要删除的machineIds
            List<String> delMachineIds = new ArrayList<String>();
            curMachineIds = ","+curMachineIds+",";
            for(int i = 0;i<dbMachineIdsArray.length;i++){
                if(!curMachineIds.contains(","+dbMachineIdsArray[i]+",")){
                    delMachineIds.add(dbMachineIdsArray[i]);
                }
            }
            //先保存信息到数据库（认证接口需要用到machine信息）
            kbrconfig.setUserId(userId);
            updateByUserId(kbrconfig);
            List<LinuxResult> linuxResults = callKDCAPINew(kbrconfig);
            ResultAPI.initAPIResult(linuxResults);
            messageList.addAll(ResultAPI.messageList);

            if(delMachineIds.size()>0){
                ClusterUser clusterUser = clusterUserMapper.findById(userId);
                List<LinuxResult> delLinuxResults = destroyClientKerberosAPINew(clusterUser.getUserName(),delMachineIds.toString());
                ResultAPI.initAPIResult(delLinuxResults);
                messageList.addAll(ResultAPI.messageList);
            }


            if (ResultAPI.flag) {
                ClusterUser clusterUser = new ClusterUser();
                clusterUser.setId(kbrconfig.getUserId());
                if(null != clientquotaList && clientquotaList.size()>0){
                    clientquotaService.saveClientDB(clusterUser,clientquotaList);
                }
                messageList.add("<div>数据库信息:修改kbr成功</div>");
            }else{
                updateByUserId(dbKbr);
                messageList.add("<div>数据库信息:修改kbr失败</div>");
            }
        }
        return messageList;
    }

    public ClusterContext initKDCAPI(Kbrconfig kbrconfig) {
        Map<String, String> parameterMap = parameterService.getAllParameter();
        List<LinuxMachine> machineList = clusterMachineService.getMachineList(null);
        CommonProperties commonProperties = new CommonProperties(parameterMap);
        ClusterUser clusterUser = clusterUserMapper.findById(kbrconfig.getUserId());
        commonProperties.setArgument(UserAPI.Cluster_User_Name, clusterUser.getUserName());
        commonProperties.setArgument(UserAPI.Cluster_User_SysPW, clusterUser.getSystemPW());
        String machineIps = clusterMachineService.getMachineIpsByIds(kbrconfig.getMachineIds());
        commonProperties.setArgument(KDCAPI.Cluster_KBR_Client, machineIps);
        ClusterContext context = new ClusterContext(commonProperties);
        context.setOriginalList(machineList);
        return context;
    }

    /**
     * update20160802qinfengxia
     * @param kbrconfig
     * @return
     */
    public Map<String, Object> initKDCAPINew(Kbrconfig kbrconfig) {
        ClusterUser clusterUser = clusterUserMapper.findById(kbrconfig.getUserId());
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(UserAPI.Cluster_User_Name, clusterUser.getUserName());
        return params;
    }

    //调用接口
    public List<LinuxResult> callKDCAPI(Kbrconfig kbrconfig) {
        ClusterContext context = initKDCAPI(kbrconfig);
        KDCAPI.authClientKerberos(context);
        return context.getContextResult().getLastResult();
    }

    /**
     * 调用接口
     * update20160802qinfengxia
     * @param kbrconfig
     * @return
     */
    public List<LinuxResult> callKDCAPINew(Kbrconfig kbrconfig) {
        Map<String, Object> params = initKDCAPINew(kbrconfig);
        System.out.println("AuthClientKerberos params==="+params.toString());
        ContextResult contextResult = KerberosAPI.AuthClientKerberos(params);
        return contextResult.getLastResult();
    }
    //删除kbr认证接口
    public List<LinuxResult> destroyClientKerberosAPI(String userName,String machineIps) {
        Map<String, String> parameterMap = parameterService.getAllParameter();
        CommonProperties commonProperties = new CommonProperties(parameterMap);
        commonProperties.setArgument(UserAPI.Cluster_User_Name, userName);
        commonProperties.setArgument(KDCAPI.Cluster_KBR_Client,machineIps);
        ClusterContext context = new ClusterContext(commonProperties);
        List<LinuxMachine> clusterMachines = clusterMachineService.getMachineList(null);
        context.setMachineList(clusterMachines);
        KDCAPI.destroyClientKerberos(context);
        return context.getContextResult().getLastResult();
    }


    /**
     * 删除kbr认证接口
     * update20160802qinfengxia
     * @param userName
     * @param machineIds
     * @return
     */
    public List<LinuxResult> destroyClientKerberosAPINew(String userName,String machineIds) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(UserAPI.Cluster_User_Name, userName);
        machineIds = machineIds.replace("[", "");
        machineIds = machineIds.replace("]", "");
        String machineIps = clusterMachineService.getMachineIpsByIds(machineIds);
        params.put(KDCAPI.Cluster_KBR_Client, machineIps);
        System.out.println("machineIds==="+machineIds);
        System.out.println("DestroyClientKerberos params===" + params.toString());
        ContextResult contextResult = KerberosAPI.DestroyClientKerberos(params);
        return contextResult.getLastResult();
    }

    /**
     * 根据用户删除kbr
     * @param userId
     */
    public void deleteByUserId(Long userId){
        kbrconfigMapper.deleteByUserId(userId);
    }


    /**
     * 批量保存
     * 1.kerbers
     * 2.client
     * 3.hdfs
     * @param kbrconfigList
     * @param noSelectList
     * @param clientquotaList
     * @param hdfsquotaList
     * @return
     */
    public Result saveBatchUpdate(List<Kbrconfig> kbrconfigList,String noSelectList,List<Clientquota> clientquotaList,List<Hdfsquota> hdfsquotaList) {
        Result result = new Result();
        result.setFlag(true);
        saveBatchKbr(kbrconfigList,noSelectList,result.getMessageList());
        saveBatchClient(clientquotaList,result.getMessageList());
        saveBatchHdsf(hdfsquotaList,result.getMessageList());
        return result;
    }

    /**
     * 保存kerbers
     * @param kbrconfigList
     * @param noSelectList
     * @param messageList
     * @return
     */
    public List<String> saveBatchKbr(List<Kbrconfig> kbrconfigList,String noSelectList,List<String> messageList){
        Map<String,Object> map = new HashMap<String,Object>();
        String[] noSelect = noSelectList.split(";");
        for (String ker : noSelect) {
            JSONObject jsonobject = JSONObject.fromObject(ker);
            map.put(jsonobject.get("userId").toString(),jsonobject.get("noSelectMachineIds").toString());
        }
        for (Kbrconfig kerconfig : kbrconfigList) {
            ClusterUser clusterUser = clusterUserMapper.findById(kerconfig.getUserId());
            //数据库里的machineIds
            Kbrconfig dbKbr = kbrconfigMapper.findByUserId(kerconfig.getUserId());
            String dbMachineIds = dbKbr.getMachineIds();
            String[]  dbMachineIdsArray = kbrconfigMapper.findByUserId(kerconfig.getUserId()).getMachineIds().split(",");
            //页面的machineIds
            String curMachineIds = kerconfig.getMachineIds();
            if(StringUtils.isNotBlank(curMachineIds)){
                //需要删除的machineIds
                List<String> delMachineIds = new ArrayList<String>();
                curMachineIds = ","+curMachineIds+",";
                for(int i = 0;i<dbMachineIdsArray.length;i++){
                    if(!curMachineIds.contains(","+dbMachineIdsArray[i]+",")){
                        delMachineIds.add(dbMachineIdsArray[i]);
                    }
                }
                updateByUserId(kerconfig);
                List<LinuxResult> linuxResults = callKDCAPINew(kerconfig);
                ResultAPI.initAPIResult(linuxResults);
                messageList.addAll(ResultAPI.messageList);

                if(delMachineIds.size()>0){
                    List<LinuxResult> delLinuxResults = destroyClientKerberosAPINew(clusterUser.getUserName(),delMachineIds.toString());
                    ResultAPI.initAPIResult(delLinuxResults);
                    messageList.addAll(ResultAPI.messageList);
                }

                if (!ResultAPI.flag) {
                    updateByUserId(dbKbr);
                    messageList.add("<div>数据库信息:用户["+clusterUser.getUserName()+"]修改kbr失败</div>");
                }else{
                    messageList.add("<div>数据库信息:用户["+clusterUser.getUserName()+"]修改kbr成功</div>");
                }
            }else{
                String pageMachineIds = map.get(kerconfig.getUserId().toString()).toString();
                if(StringUtils.isNotBlank(pageMachineIds)){
                    List<LinuxResult> delLinuxResults = destroyClientKerberosAPINew(clusterUser.getUserName(),pageMachineIds);
                    ResultAPI.initAPIResult(delLinuxResults);
                    messageList.addAll(ResultAPI.messageList);
                    kerconfig.setMachineIds(curMachineIds);
                }else{
                    kerconfig.setMachineIds(dbMachineIds);
                }
                updateByUserId(kerconfig);
                if (!ResultAPI.flag) {
                    updateByUserId(dbKbr);
                }else{
                    messageList.add("<div>数据库信息:用户[" + clusterUser.getUserName() + "]修改kbr成功</div>");
                }

            }

        }
        return messageList;
    }

    /**
     *保存client
     * @param clientquotaList
     * @param messageList
     * @return
     */
    public List<String> saveBatchClient(List<Clientquota> clientquotaList, List<String> messageList ){
        if(null != clientquotaList && clientquotaList.size()>0){
            for(Clientquota client :clientquotaList){
                ClusterUser user = clusterUserMapper.findById(client.getUserId());
                clientquotaService.saveClientDB(client);
            }
        }
        return messageList;
    }

    /**
     * 保存hdfs
     * @param hdfsquotaList
     * @param messageList
     * @return
     */
    public List<String> saveBatchHdsf(List<Hdfsquota> hdfsquotaList, List<String> messageList ){
        if(null != hdfsquotaList && hdfsquotaList.size()>0){
            for(Hdfsquota hdfsquota:hdfsquotaList){
                ClusterUser user = clusterUserMapper.findById(hdfsquota.getUserId());
                //初始化数据
                Map<String, Object> params = new HashMap<String, Object>();
                params.put(UserAPI.Cluster_User_Name, user.getUserName());

                if (hdfsquota != null) {
                    String sSpace = hdfsquota.getHdfsSpace() == null ? null : hdfsquotaService.changeUntil(hdfsquota);
                    params.put(HDFSAPI.HDFS_QUOTA_SPACE_SIZE, sSpace);
                    String fileCount = hdfsquota.getHdfsFileCount() == null ? null : hdfsquota.getHdfsFileCount().toString();
                    params.put(HDFSAPI.HDFS_QUOTA_DIR_NUMBER, fileCount);
                    ContextResult contextResult = HadoopHDFSAPI.QuotaHadoopHDFS(params);
                    ResultAPI.initAPIResult(contextResult.getLastResult());
                    messageList.addAll(ResultAPI.messageList);//调用接口返回的信息
                    if (ResultAPI.flag) {
                        hdfsquotaService.updateHDFSDB(hdfsquota);
                        messageList.add("<div>数据库信息:用户["+user.getUserName()+"]修改hdfs成功!</div>");
                    }
                }

            }
        }
        return messageList;
    }
}
